﻿Imports WiremetModel.Entities.OEM
Imports WiremetModel.Exceptions

Public Class GatunekView


    Private _unitOfWork As UnitOfWork
    Private _gatunekDictionary As IDictionary(Of Integer, Gatunek)

    Private Structure Filter
        Public PolishName As String
        Public EnglishName As String
        Public GermanName As String
        Public NormaId As Integer
    End Structure

    Public Sub New()
        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshView()
    End Sub

    Private Sub GatunekView_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub

    Private Sub RefreshView()
        RefreshViewData()
        RefreshGatunekTable(_gatunekDictionary.Values)
    End Sub

    Private Sub RefreshViewData()

        Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)
        _gatunekDictionary = gatunekRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        RefreshNormaFilterComboBox()

    End Sub

    Private Sub RefreshNormaFilterComboBox()
        Dim normaRepository As New Repository(Of Norma)(_unitOfWork)
        Dim normaList As IEnumerable(Of Norma) = normaRepository.GetAll()
        InitializeFilterComboBox(cmb_Filter_Norma, normaList)
    End Sub


    Private Sub InitializeFilterComboBox(ByRef filterComboBox As ComboBox, ByVal data As IEnumerable(Of Object))

        filterComboBox.DataSource = New BindingSource(data, Nothing)
        filterComboBox.AutoCompleteCustomSource.Clear()
        filterComboBox.AutoCompleteCustomSource.AddRange(data.Select(Function(x) x.ToString()).ToArray())
        filterComboBox.SelectedIndex = -1

    End Sub


    Private Sub RefreshGatunekTable(ByVal gatunekList As IEnumerable(Of Gatunek))
        dgv_Gatunek.Rows.Clear()
        For Each gatunek As Gatunek In gatunekList.OrderBy(Function(x) x.NazwaAng)
            AddGatunekRow(gatunek)
        Next
    End Sub

    Private Function AddGatunekRow(ByVal gatunek As Gatunek) As Integer
        Return dgv_Gatunek.Rows.Add(
                gatunek.Id,
                dgv_Gatunek.RowCount + 1,
                gatunek.NazwaAng,
                gatunek.Nazwa,
                gatunek.NazwaNiem,
                If(IsNothing(gatunek.Stop), String.Empty, gatunek.Stop.Nazwa),
                (gatunek.VAT * 100).ToString("G29") & " %"
            )
    End Function


    Private Function GetSelectedGatunek() As Gatunek
        If dgv_Gatunek.SelectedRows.Count = 0 Then
            Return Nothing
        Else
            Return _gatunekDictionary(CInt(dgv_Gatunek.SelectedRows(0).Cells("GatunekId").Value))
        End If
    End Function


#Region "Filter"

    Private Function GetFilter() As Filter
        Return New Filter With
        {
            .PolishName = tb_Filter_PolishName.Text.Trim(),
            .EnglishName = tb_Filter_EnglishName.Text.Trim(),
            .GermanName = tb_Filter_GermanName.Text.Trim(),
            .NormaId = If(IsNothing(cmb_Filter_Norma.SelectedItem), 0, CType(cmb_Filter_Norma.SelectedItem, Norma).Id)
        }
    End Function

    Private Function IsGatunekSatisfiedByFilter(ByVal gatunek As Gatunek, ByVal filter As Filter) As Boolean
        Return gatunek.NazwaAng.StartsWith(filter.EnglishName, StringComparison.CurrentCultureIgnoreCase) AndAlso
               gatunek.Nazwa.StartsWith(filter.PolishName, StringComparison.CurrentCultureIgnoreCase) AndAlso
               gatunek.NazwaNiem.StartsWith(filter.GermanName, StringComparison.CurrentCultureIgnoreCase) AndAlso
               (filter.NormaId = 0 OrElse gatunek.NormaAsocList.Any(Function(x) x.Norma.Id = filter.NormaId))
    End Function

    Private Sub RunFilter(ByVal filter As Filter)
        Dim filteredGatunekList As New List(Of Gatunek)

        For Each gatunek As Gatunek In _gatunekDictionary.Values
            If IsGatunekSatisfiedByFilter(gatunek, filter) Then
                filteredGatunekList.Add(gatunek)
            End If
        Next
        RefreshGatunekTable(filteredGatunekList)
    End Sub

    Private Sub ClearFilter()

        tb_Filter_EnglishName.Text = String.Empty
        tb_Filter_GermanName.Text = String.Empty
        tb_Filter_PolishName.Text = String.Empty
        cmb_Filter_Norma.ResetText()
        cmb_Filter_Norma.SelectedIndex = -1

    End Sub


    Private Sub btn_RunFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter(GetFilter())
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RefreshGatunekTable(_gatunekDictionary.Values)
    End Sub

    Private Sub filterInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tb_Filter_EnglishName.KeyDown, tb_Filter_GermanName.KeyDown, tb_Filter_PolishName.KeyDown, cmb_Filter_Norma.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter(GetFilter())
        End If
    End Sub

#End Region

    Private Sub EnsureGatunekIsSelected()
        If dgv_Gatunek.SelectedRows.Count = 0 Then
            Throw New Exception("Proszę, wybierz gatunek, aby kontynuować.")
        End If
    End Sub


    Private Sub ts_btn_AddGatunek_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_AddGatunek.Click
        Try
            Dim gatunekInputDialog As New GatunekInputDialog(_unitOfWork)
            If gatunekInputDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Cursor = Cursors.WaitCursor

                Dim gatunek As Gatunek = gatunekInputDialog.Gatunek
                Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                gatunekRepository.Add(gatunek)
                _unitOfWork.CommitTransaction()

                _gatunekDictionary.Add(gatunek.Id, gatunek)
                Dim newRowIndex As Integer = AddGatunekRow(gatunek)
                dgv_Gatunek.Rows(newRowIndex).Selected = True
                dgv_Gatunek.Sort(dgv_Gatunek.Columns("NazwaAng"), System.ComponentModel.ListSortDirection.Ascending)
                dgv_Gatunek.FirstDisplayedScrollingRowIndex = newRowIndex
                RefreshNormaFilterComboBox()

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub


    Private Sub EditGatunek()
        Try
            EnsureGatunekIsSelected()
            Dim selectedRowIndex As Integer = dgv_Gatunek.SelectedRows(0).Index
            Dim selectedGatunek As Gatunek = GetSelectedGatunek()

            Dim gatunekInputDialog As New GatunekInputDialog(_unitOfWork, selectedGatunek)
            If gatunekInputDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Cursor = Cursors.WaitCursor

                Dim gatunek As Gatunek = gatunekInputDialog.Gatunek
                Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                gatunekRepository.Update(gatunek)
                _unitOfWork.CommitTransaction()

                _gatunekDictionary(selectedGatunek.Id) = gatunek
                dgv_Gatunek.Rows.RemoveAt(selectedRowIndex)
                dgv_Gatunek.Rows(AddGatunekRow(gatunek)).Selected = True
                dgv_Gatunek.Sort(dgv_Gatunek.Columns("NazwaAng"), System.ComponentModel.ListSortDirection.Ascending)
                RefreshNormaFilterComboBox()

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_EditGatunek_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_EditGatunek.Click
        EditGatunek()
    End Sub

    Private Sub dgv_Gatunek_CellDoubleClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv_Gatunek.CellDoubleClick
        EditGatunek()
    End Sub

    Private Sub ts_btn_RemoveGatunek_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RemoveGatunek.Click
        Try
            EnsureGatunekIsSelected()
            Dim selectedGatunek As Gatunek = GetSelectedGatunek()
            Dim selectedRowIndex As Integer = dgv_Gatunek.SelectedRows(0).Index
            Dim confirmationDialogResult As DialogResult = MessageBox.Show("Czy jesteś pewien?", "Uwaga", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)

            If confirmationDialogResult = DialogResult.Yes Then
                Cursor = Cursors.WaitCursor

                Dim gatunekRepository As New Repository(Of Gatunek)(_unitOfWork)

                _unitOfWork.BeginTransaction()
                gatunekRepository.Delete(selectedGatunek)
                _unitOfWork.CommitTransaction()

                _gatunekDictionary.Remove(selectedGatunek.Id)
                dgv_Gatunek.Rows.RemoveAt(selectedRowIndex)

            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub ts_btn_RefreshView_Click(sender As System.Object, e As System.EventArgs) Handles ts_btn_RefreshView.Click
        Try
            Cursor = Cursors.WaitCursor
            _unitOfWork.Dispose()
            _unitOfWork = New UnitOfWork()
            RefreshView()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub


    
End Class